﻿using SQ.BLL.Factory;
using SQ.BLL.Interfaces;
using SQ.Calculadora.Implementations;
using SQ.Calculadora.Interfaces;
using SQ.Core.FilaProcessor.Interface;
using SQ.Domain;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SQ.Core.FilaProcessor
{
    public class FilaProcessor : IFilaProcessor
    {
        private ICalculadora Calculadora;
        private IIntegranteFilaBS integranteFilaBS;
        private IFilaBS filaBS;

        public FilaProcessor()
        {
            this.integranteFilaBS = BLLFactory.getIntegranteFilaBS();
            this.filaBS = BLLFactory.getFilaBS();
        }

        public void CalcularTempoMedioFila(Fila fila)
        {
            var listaIntegrantesFila = this.integranteFilaBS.ObterIntegrantesFila(fila.Id);

            if (listaIntegrantesFila != null && listaIntegrantesFila.Count > 0)
            {
                int quantidadeIntegrantesFila = listaIntegrantesFila.Count;                
                List<int> listaDiferencaEntreTempoEntradaESaida = RetornarDiferencasDeTempoDeEspera(listaIntegrantesFila);

                this.Calculadora = new CalculadoraMediaAritmetica(listaDiferencaEntreTempoEntradaESaida);
                
                fila.TempoEsperaMedio = this.Calculadora.CalcularTempoEspera();
            }
            else
            {
                fila.TempoEsperaMedio = 0;
            }

            this.filaBS.AtualizarFila(fila);
        }

        private List<int> RetornarDiferencasDeTempoDeEspera(IList<IntegranteFila> listaIntegrantesFila)
        {
            List<int> listaDiferencas = new List<int>();

            double diferencaEmMinutos;
            foreach (var integrante in listaIntegrantesFila)
            {
                diferencaEmMinutos = 0;
                if (integrante.DataSaidaFila == null || integrante.DataSaidaFila == DateTime.MinValue)
                {
                    diferencaEmMinutos = ObterDiferencaEmMinutos(DateTime.Now, integrante.DataEntradaFila);
                }
                else
                {
                    diferencaEmMinutos = ObterDiferencaEmMinutos(integrante.DataSaidaFila, integrante.DataEntradaFila);
                }

                listaDiferencas.Add(Convert.ToInt32(diferencaEmMinutos));
            }

            return listaDiferencas;
        }

        private double ObterDiferencaEmMinutos(DateTime dataFim, DateTime dataInicio)
        {
            return (dataFim - dataInicio).TotalMinutes;
        }
    }
}
